package hs.avr_net_io_panel;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;

public class NetworkService extends Service {
	private NotificationManager mNM;
	private AvrNetIo mAvrNetIoConnection;
	private Handler mCallbackHandler;

	/**
	 * Class for clients to access. Because we know this service always runs in
	 * the same process as its clients, we don't need to deal with IPC.
	 */
	/*
	 * public class LocalBinder extends Binder { NetworkService getService() {
	 * return NetworkService.this; } }
	 */

	@Override
	public IBinder onBind(Intent intent) {
		return mNetworkServiceBinder;
	}

	@Override
	public void onCreate() {
		mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
		showNotification();
		Toast.makeText(this, "Service created ...", Toast.LENGTH_LONG).show();
		Log.i("LocalService", "Created");
		super.onCreate();
	}

	// This is the object that receives interactions from clients. See
	// RemoteService for a more complete example.
	// private final IBinder mBinder = new LocalBinder();

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.i("LocalService", "Received start id " + startId + ": " + intent);

		final SharedPreferences settings = SettingsActivity
				.getAppSettings(this);
		final String ipAddress = settings.getString("ipaddress", "unknown");
		final String port = settings.getString("port", "50290");
		final String timeout = settings.getString("timeout", "10000");
		boolean temp = _connectToAvrNetIO(ipAddress, Integer.valueOf(port),
				Integer.valueOf(timeout));

		// We want this service to continue running until it is explicitly
		// stopped, so return sticky.
		return START_STICKY;
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		threadstop = true;
		Toast.makeText(this, "Service destroyed ...", Toast.LENGTH_LONG).show();
		Log.i("LocalService", "Destroyed");
		// Cancel the persistent notification.
		mNM.cancel(R.string.network_service_started);
	}

	/**
	 * Show a notification while this service is running.
	 */
	private void showNotification() {
		// In this sample, we'll use the same text for the ticker and the
		// expanded notification
		CharSequence text = getText(R.string.network_service_started);

		// Set the icon, scrolling text and timestamp
		Notification notification = new Notification(R.drawable.icon, text,
				System.currentTimeMillis());

		// The PendingIntent to launch our activity if the user selects this
		// notification
		PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
				new Intent(this, MainActivity.class), 0);

		// Set the info for the views that show in the notification panel.
		notification.setLatestEventInfo(this,
				getText(R.string.network_service_label), text, contentIntent);

		// Send the notification.
		// We use a layout id because it is a unique number. We use it later to
		// cancel.
		mNM.notify(R.string.network_service_started, notification);
	}

	private final IBinder mNetworkServiceBinder = new NetworkServiceBinder();
	private volatile boolean mIsBusy = false;
	private volatile boolean threadstop = false;

	public class NetworkServiceBinder extends Binder {

		public void setActivityCallbackHandler(final Handler callback) {
			mCallbackHandler = callback;
		}

		public void readValuesFromAvrNetIo() {
			
			if (mIsBusy)
				return;
			
			new Thread() {
				@Override
				public void run() {
					mIsBusy = true;
					
					while (!threadstop) {
						
					final Message msg = new Message();
					final Bundle bundle = new Bundle();
					int[] adcValues = new int[4];
					boolean[] digitalInputValues = new boolean[8];

					
						adcValues = _getADC();
						bundle.putIntArray("adc", adcValues);
						/*
						try {
							sleep(1000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}*/
						digitalInputValues = _getDigitalInputs();
						bundle.putBooleanArray("digitalInputs",
								digitalInputValues);

						msg.setData(bundle);
						mCallbackHandler.sendMessage(msg);
						// TODO: Ist dieser Sleep notwendig?
						try {
							sleep(500);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							Log.e("Network Service: ", "Thread Interrupted Exception");
						}
						mIsBusy = false;
						
						  //try { sleep(8000); } catch (InterruptedException e) {						 
						  //e.printStackTrace(); }
						 
					}
				}
			}.start();
		}
	} // Ende der Binder Implementierung

	private boolean _connectToAvrNetIO(String ipAddress, int port, int timeout) {
		mAvrNetIoConnection = new AvrNetIo(ipAddress, port, timeout);
		return mAvrNetIoConnection.connect();
		// return true;
	}

	private int[] _getADC() {
		int[] adcValues = new int[4];
		adcValues[0] = 10;// mAvrNetIoConnection.getADC(1);
		adcValues[1] = 11;// mAvrNetIoConnection.getADC(2);
		adcValues[2] = 12;// mAvrNetIoConnection.getADC(3);
		adcValues[3] = 13;// mAvrNetIoConnection.getADC(4);
		return adcValues;
	}

	private boolean[] _getDigitalInputs() {
		boolean[] digitalInputValues = new boolean[8];
		for (int i = 0; i < 8; i++) {
			digitalInputValues[i] = Boolean.valueOf(Integer
					.toString(/*mAvrNetIoConnection.getOutPort(i + 1)*/55));
		}
		return digitalInputValues;

	}

}
